package czy.demo.config;

import czy.demo.service.security.UserDetailServiceImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.crypto.password.Pbkdf2PasswordEncoder;
import org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler;

/* 安全配置 */
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {

    private static final Logger logger = LoggerFactory.getLogger(SpringSecurityConfig.class);

    @Value("${system.password.secret}")
    private String secret;

    @Bean
    public PasswordEncoder passwordEncoder(){
        return new Pbkdf2PasswordEncoder(secret);
    }

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Autowired
    private UserDetailServiceImpl userDetailService;

    /* 认证管理器配置 */
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        /* 配置了认证服务于密码编码器 */
        auth.userDetailsService(userDetailService).passwordEncoder(passwordEncoder);
    }

    /* 基本不用配置 */
    @Override
    public void configure(WebSecurity web) throws Exception {
        super.configure(web);
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {

        /* 配置表单登录 */
        http.formLogin()
                /* 表单登录页面，使用GET请求访问 */
                .loginPage("/login")
                /* 表单登录过滤器拦截url， 使用POST请求访问*/
                .loginProcessingUrl("/login")
                /* 表单登录失败，请求转发url */
                .failureForwardUrl("/login?error=true")
                /* 表单登录成功，转发URL，这里采用请求转发，浏览器地址栏不变 */
                //.successForwardUrl("/index")
                /* 这里采用重定向，浏览器地址栏会改变 */
                .successHandler(new SimpleUrlAuthenticationSuccessHandler("/index"));

        /* 启用csrf保护，此项目中通过meta标签传递csrf token */
        http.csrf();

        /* 登出配置 */
        http.logout()
                /* 登出时配置认证信息 */
                .clearAuthentication(true)
                /* 登出时，删除的cookie */
                .deleteCookies("")
                /* 登出时使会话无效 */
                .invalidateHttpSession(true)
                /* 登出拦截url，过滤器使用 */
                .logoutUrl("/logout")
                /* 登出后，重定向url */
                .logoutSuccessUrl("/login");

        /* 记住我服务 */
        http.rememberMe();

        /* servlet api支持 */
        http.servletApi().rolePrefix("ROLE_");

        /* session 配置 */
        http.sessionManagement()
                /* session id的url重写 */
                .enableSessionUrlRewriting(false);


    }
}
